use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use anyhow::{Result, anyhow};
use tokio::fs;
use log::{info, error, debug, warn};
use uuid::Uuid;
use crate::ssh::{AuthMethod, SshConfig};
use crate::tunnel::{TunnelConfig, TunnelType};
use crate::terminal::TerminalSize;

/// 应用程序配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AppConfig {
    /// 应用版本
    pub version: String,
    /// 配置文件路径
    pub config_dir: PathBuf,
    /// 日志级别
    pub log_level: String,
    /// 主题设置
    pub theme: ThemeConfig,
    /// 终端默认设置
    pub terminal_defaults: TerminalDefaults,
    /// 安全设置
    pub security: SecurityConfig,
    /// 最近使用的连接
    pub recent_connections: Vec<String>,
    /// 窗口设置
    pub window: WindowConfig,
}

impl Default for AppConfig {
    fn default() -> Self {
        Self {
            version: env!("CARGO_PKG_VERSION").to_string(),
            config_dir: get_default_config_dir(),
            log_level: "info".to_string(),
            theme: ThemeConfig::default(),
            terminal_defaults: TerminalDefaults::default(),
            security: SecurityConfig::default(),
            recent_connections: Vec::new(),
            window: WindowConfig::default(),
        }
    }
}

/// 主题配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ThemeConfig {
    pub name: String,
    pub background_color: String,
    pub foreground_color: String,
    pub cursor_color: String,
    pub selection_color: String,
    pub font_family: String,
    pub font_size: u32,
}

impl Default for ThemeConfig {
    fn default() -> Self {
        Self {
            name: "default".to_string(),
            background_color: "#1e1e1e".to_string(),
            foreground_color: "#d4d4d4".to_string(),
            cursor_color: "#ffffff".to_string(),
            selection_color: "#264f78".to_string(),
            font_family: "Consolas, 'Courier New', monospace".to_string(),
            font_size: 14,
        }
    }
}

/// 终端默认设置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TerminalDefaults {
    pub size: TerminalSize,
    pub shell: Option<String>,
    pub scrollback_lines: u32,
    pub cursor_blink: bool,
    pub bell_enabled: bool,
}

impl Default for TerminalDefaults {
    fn default() -> Self {
        Self {
            size: TerminalSize::default(),
            shell: None,
            scrollback_lines: 1000,
            cursor_blink: true,
            bell_enabled: true,
        }
    }
}

/// 安全配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecurityConfig {
    /// 是否加密保存的密码
    pub encrypt_passwords: bool,
    /// 密钥文件权限检查
    pub check_key_permissions: bool,
    /// 主机密钥验证
    pub verify_host_keys: bool,
    /// 已知主机文件路径
    pub known_hosts_file: Option<PathBuf>,
    /// 会话超时时间（秒）
    pub session_timeout: Option<u64>,
}

impl Default for SecurityConfig {
    fn default() -> Self {
        Self {
            encrypt_passwords: true,
            check_key_permissions: true,
            verify_host_keys: true,
            known_hosts_file: None,
            session_timeout: Some(3600), // 1小时
        }
    }
}

/// 窗口配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WindowConfig {
    pub width: u32,
    pub height: u32,
    pub maximized: bool,
    pub always_on_top: bool,
}

impl Default for WindowConfig {
    fn default() -> Self {
        Self {
            width: 1200,
            height: 800,
            maximized: false,
            always_on_top: false,
        }
    }
}

/// 连接配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConnectionConfig {
    pub id: String,
    pub name: String,
    pub ssh_config: SshConfig,
    pub tunnels: Vec<TunnelConfig>,
    pub terminal_config: TerminalConfigOverride,
    pub tags: Vec<String>,
    pub notes: Option<String>,
    pub created_at: chrono::DateTime<chrono::Utc>,
    pub last_used: Option<chrono::DateTime<chrono::Utc>>,
    pub use_count: u64,
}

impl ConnectionConfig {
    pub fn new(name: String, ssh_config: SshConfig) -> Self {
        Self {
            id: Uuid::new_v4().to_string(),
            name,
            ssh_config,
            tunnels: Vec::new(),
            terminal_config: TerminalConfigOverride::default(),
            tags: Vec::new(),
            notes: None,
            created_at: chrono::Utc::now(),
            last_used: None,
            use_count: 0,
        }
    }

    pub fn with_tunnel(mut self, tunnel: TunnelConfig) -> Self {
        self.tunnels.push(tunnel);
        self
    }

    pub fn with_tag(mut self, tag: String) -> Self {
        self.tags.push(tag);
        self
    }

    pub fn with_notes(mut self, notes: String) -> Self {
        self.notes = Some(notes);
        self
    }

    pub fn mark_used(&mut self) {
        self.last_used = Some(chrono::Utc::now());
        self.use_count += 1;
    }
}

/// 终端配置覆盖
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TerminalConfigOverride {
    pub size: Option<TerminalSize>,
    pub shell: Option<String>,
    pub env_vars: HashMap<String, String>,
    pub working_directory: Option<String>,
}

impl Default for TerminalConfigOverride {
    fn default() -> Self {
        Self {
            size: None,
            shell: None,
            env_vars: HashMap::new(),
            working_directory: None,
        }
    }
}

/// 配置管理器
pub struct ConfigManager {
    config_dir: PathBuf,
    app_config: AppConfig,
    connections: HashMap<String, ConnectionConfig>,
}

impl ConfigManager {
    /// 创建新的配置管理器
    pub async fn new() -> Result<Self> {
        let config_dir = get_default_config_dir();
        
        // 确保配置目录存在
        fs::create_dir_all(&config_dir).await
            .map_err(|e| anyhow!("创建配置目录失败: {}", e))?;
        
        let mut manager = Self {
            config_dir: config_dir.clone(),
            app_config: AppConfig::default(),
            connections: HashMap::new(),
        };
        
        // 加载配置
        manager.load_app_config().await?;
        manager.load_connections().await?;
        
        Ok(manager)
    }

    /// 加载应用配置
    pub async fn load_app_config(&mut self) -> Result<()> {
        let config_file = self.config_dir.join("app.toml");
        
        if config_file.exists() {
            let content = fs::read_to_string(&config_file).await
                .map_err(|e| anyhow!("读取应用配置失败: {}", e))?;
            
            self.app_config = toml::from_str(&content)
                .map_err(|e| anyhow!("解析应用配置失败: {}", e))?;
            
            info!("加载应用配置成功: {:?}", config_file);
        } else {
            // 创建默认配置文件
            self.save_app_config().await?;
            info!("创建默认应用配置: {:?}", config_file);
        }
        
        Ok(())
    }

    /// 保存应用配置
    pub async fn save_app_config(&self) -> Result<()> {
        let config_file = self.config_dir.join("app.toml");
        
        let content = toml::to_string_pretty(&self.app_config)
            .map_err(|e| anyhow!("序列化应用配置失败: {}", e))?;
        
        fs::write(&config_file, content).await
            .map_err(|e| anyhow!("保存应用配置失败: {}", e))?;
        
        info!("保存应用配置成功: {:?}", config_file);
        Ok(())
    }

    /// 加载连接配置
    pub async fn load_connections(&mut self) -> Result<()> {
        let connections_dir = self.config_dir.join("connections");
        
        if !connections_dir.exists() {
            fs::create_dir_all(&connections_dir).await
                .map_err(|e| anyhow!("创建连接配置目录失败: {}", e))?;
            return Ok(());
        }
        
        let mut entries = fs::read_dir(&connections_dir).await
            .map_err(|e| anyhow!("读取连接配置目录失败: {}", e))?;
        
        while let Some(entry) = entries.next_entry().await
            .map_err(|e| anyhow!("读取目录条目失败: {}", e))? {
            
            let path = entry.path();
            if path.extension().and_then(|s| s.to_str()) == Some("toml") {
                match self.load_connection_file(&path).await {
                    Ok(connection) => {
                        self.connections.insert(connection.id.clone(), connection);
                    }
                    Err(e) => {
                        error!("加载连接配置失败 {:?}: {}", path, e);
                    }
                }
            }
        }
        
        info!("加载了 {} 个连接配置", self.connections.len());
        Ok(())
    }

    /// 加载单个连接配置文件
    async fn load_connection_file(&self, path: &Path) -> Result<ConnectionConfig> {
        let content = fs::read_to_string(path).await
            .map_err(|e| anyhow!("读取连接配置文件失败: {}", e))?;
        
        let connection: ConnectionConfig = toml::from_str(&content)
            .map_err(|e| anyhow!("解析连接配置失败: {}", e))?;
        
        debug!("加载连接配置: {} ({})", connection.name, connection.id);
        Ok(connection)
    }

    /// 保存连接配置
    pub async fn save_connection(&mut self, connection: ConnectionConfig) -> Result<()> {
        let connections_dir = self.config_dir.join("connections");
        fs::create_dir_all(&connections_dir).await
            .map_err(|e| anyhow!("创建连接配置目录失败: {}", e))?;
        
        let filename = format!("{}.toml", connection.id);
        let config_file = connections_dir.join(filename);
        
        let content = toml::to_string_pretty(&connection)
            .map_err(|e| anyhow!("序列化连接配置失败: {}", e))?;
        
        fs::write(&config_file, content).await
            .map_err(|e| anyhow!("保存连接配置失败: {}", e))?;
        
        // 更新内存中的配置
        self.connections.insert(connection.id.clone(), connection.clone());
        
        // 更新最近使用列表
        self.update_recent_connections(&connection.id);
        
        info!("保存连接配置成功: {} ({})", connection.name, connection.id);
        Ok(())
    }

    /// 删除连接配置
    pub async fn delete_connection(&mut self, connection_id: &str) -> Result<()> {
        let connections_dir = self.config_dir.join("connections");
        let filename = format!("{}.toml", connection_id);
        let config_file = connections_dir.join(filename);
        
        if config_file.exists() {
            fs::remove_file(&config_file).await
                .map_err(|e| anyhow!("删除连接配置文件失败: {}", e))?;
        }
        
        // 从内存中移除
        if let Some(connection) = self.connections.remove(connection_id) {
            info!("删除连接配置: {} ({})", connection.name, connection_id);
        }
        
        // 从最近使用列表中移除
        self.app_config.recent_connections.retain(|id| id != connection_id);
        
        Ok(())
    }

    /// 获取连接配置
    pub fn get_connection(&self, connection_id: &str) -> Option<&ConnectionConfig> {
        self.connections.get(connection_id)
    }

    /// 获取所有连接配置
    pub fn get_all_connections(&self) -> Vec<&ConnectionConfig> {
        self.connections.values().collect()
    }

    /// 按标签筛选连接
    pub fn get_connections_by_tag(&self, tag: &str) -> Vec<&ConnectionConfig> {
        self.connections.values()
            .filter(|conn| conn.tags.contains(&tag.to_string()))
            .collect()
    }

    /// 搜索连接
    pub fn search_connections(&self, query: &str) -> Vec<&ConnectionConfig> {
        let query_lower = query.to_lowercase();
        
        self.connections.values()
            .filter(|conn| {
                conn.name.to_lowercase().contains(&query_lower) ||
                conn.ssh_config.host.to_lowercase().contains(&query_lower) ||
                conn.tags.iter().any(|tag| tag.to_lowercase().contains(&query_lower)) ||
                conn.notes.as_ref().map_or(false, |notes| notes.to_lowercase().contains(&query_lower))
            })
            .collect()
    }

    /// 获取最近使用的连接
    pub fn get_recent_connections(&self) -> Vec<&ConnectionConfig> {
        self.app_config.recent_connections.iter()
            .filter_map(|id| self.connections.get(id))
            .collect()
    }

    /// 更新最近使用的连接列表
    fn update_recent_connections(&mut self, connection_id: &str) {
        // 移除已存在的条目
        self.app_config.recent_connections.retain(|id| id != connection_id);
        
        // 添加到开头
        self.app_config.recent_connections.insert(0, connection_id.to_string());
        
        // 限制列表长度
        if self.app_config.recent_connections.len() > 10 {
            self.app_config.recent_connections.truncate(10);
        }
    }

    /// 标记连接为已使用
    pub async fn mark_connection_used(&mut self, connection_id: &str) -> Result<()> {
        let connection_to_save = if let Some(connection) = self.connections.get_mut(connection_id) {
            connection.mark_used();
            Some(connection.clone())
        } else {
            None
        };
        
        if let Some(connection) = connection_to_save {
            self.save_connection(connection).await?;
        }
        Ok(())
    }

    /// 获取应用配置
    pub fn get_app_config(&self) -> &AppConfig {
        &self.app_config
    }

    /// 更新应用配置
    pub async fn update_app_config<F>(&mut self, updater: F) -> Result<()>
    where
        F: FnOnce(&mut AppConfig),
    {
        updater(&mut self.app_config);
        self.save_app_config().await
    }

    /// 导出连接配置
    pub async fn export_connections(&self, export_path: &Path) -> Result<()> {
        let export_data = ExportData {
            version: self.app_config.version.clone(),
            connections: self.connections.values().cloned().collect(),
            exported_at: chrono::Utc::now(),
        };
        
        let content = toml::to_string_pretty(&export_data)
            .map_err(|e| anyhow!("序列化导出数据失败: {}", e))?;
        
        fs::write(export_path, content).await
            .map_err(|e| anyhow!("写入导出文件失败: {}", e))?;
        
        info!("导出 {} 个连接配置到: {:?}", export_data.connections.len(), export_path);
        Ok(())
    }

    /// 导入连接配置
    pub async fn import_connections(&mut self, import_path: &Path) -> Result<usize> {
        let content = fs::read_to_string(import_path).await
            .map_err(|e| anyhow!("读取导入文件失败: {}", e))?;
        
        let import_data: ExportData = toml::from_str(&content)
            .map_err(|e| anyhow!("解析导入数据失败: {}", e))?;
        
        let mut imported_count = 0;
        
        for connection in import_data.connections {
            // 检查是否已存在同名连接
            let existing = self.connections.values()
                .any(|c| c.name == connection.name);
            
            if existing {
                warn!("跳过已存在的连接: {}", connection.name);
                continue;
            }
            
            self.save_connection(connection).await?;
            imported_count += 1;
        }
        
        info!("导入了 {} 个连接配置", imported_count);
        Ok(imported_count)
    }
}

/// 导出数据结构
#[derive(Debug, Serialize, Deserialize)]
struct ExportData {
    version: String,
    connections: Vec<ConnectionConfig>,
    exported_at: chrono::DateTime<chrono::Utc>,
}

/// 获取默认配置目录
fn get_default_config_dir() -> PathBuf {
    if let Some(config_dir) = dirs::config_dir() {
        config_dir.join("rustshell")
    } else {
        PathBuf::from(".rustshell")
    }
}

/// 便捷函数：创建SSH连接配置
pub fn create_ssh_connection_config(
    name: String,
    host: String,
    port: u16,
    username: String,
    auth_method: AuthMethod,
) -> ConnectionConfig {
    let ssh_config = SshConfig {
        host,
        port,
        username,
        auth_method,
        password: None,
        private_key_path: None,
        connect_timeout: Some(30),
        keepalive_interval: Some(60)
    };
    
    ConnectionConfig::new(name, ssh_config)
}

/// 便捷函数：创建带隧道的连接配置
pub fn create_connection_with_tunnel(
    name: String,
    host: String,
    port: u16,
    username: String,
    auth_method: AuthMethod,
    local_port: u16,
    remote_host: String,
    remote_port: u16,
) -> ConnectionConfig {
    let mut connection = create_ssh_connection_config(name, host, port, username, auth_method);
    
    let tunnel_config = TunnelConfig::new(
        format!("隧道-{}-{}", local_port, remote_port),
        TunnelType::Local {
            local_port,
            remote_host,
            remote_port,
        },
        connection.id.clone(),
    );
    
    connection = connection.with_tunnel(tunnel_config);
    connection
}